/**
 * @file 异步任务服务
 * @description 提供异步任务的 CRUD 操作和查询功能
 * @author AI Assistant
 * @version 1.0.0
 * @since 2025-10-30
 */

import Realm from 'realm'
import type {
  CreateAsyncTaskInput,
  DatabaseResult,
  ParsedAsyncTask,
  QueryAsyncTaskParams,
  UpdateAsyncTaskInput
} from '../models/async-task.model'
import { AsyncTaskModel, TaskStatus } from '../models/async-task.model'
import { getDatabase } from '#/database'

/**
 * 异步任务服务类
 */
export class AsyncTaskService {
  private static instance: AsyncTaskService | null = null

  /**
   * 获取服务实例（单例模式）
   */
  static getInstance(): AsyncTaskService {
    if (!this.instance) {
      this.instance = new AsyncTaskService()
    }
    return this.instance
  }

  /**
   * 私有构造函数
   */
  private constructor() {
    // 私有构造函数，确保单例模式
  }

  /**
   * 获取下一个数值ID
   * @param realm Realm 实例
   * @returns 下一个可用的数值ID
   */
  private getNextLegacyId(realm: Realm): number {
    const withIds = realm.objects('AsyncTask').filtered('id != nil') as unknown as AsyncTaskModel[]
    if (withIds.length === 0) return 1
    const max = withIds.reduce((m, r) => (r.id && r.id > m ? r.id : m), 0)
    return (max || 0) + 1
  }

  /**
   * 将 AsyncTaskModel 转换为 ParsedAsyncTask
   * @param model Realm 模型实例
   * @returns 解析后的任务对象
   */
  private parseTaskModel(model: AsyncTaskModel): ParsedAsyncTask {
    return {
      _id: model._id.toHexString(),
      id: model.id,
      task_type: model.task_type,
      business_data: JSON.parse(model.business_data),
      status: model.status as TaskStatus,
      progress: model.progress,
      error_message: model.error_message,
      result_data: model.result_data ? JSON.parse(model.result_data) : null,
      created_at: model.created_at,
      updated_at: model.updated_at,
      started_at: model.started_at,
      completed_at: model.completed_at
    }
  }

  /**
   * 创建异步任务
   * @param input 任务创建输入数据
   * @returns 操作结果
   */
  async createTask(input: CreateAsyncTaskInput): Promise<DatabaseResult<ParsedAsyncTask>> {
    try {
      const realm = getDatabase()
      const now = new Date()

      let newTask: AsyncTaskModel

      realm.write(() => {
        const nextId = this.getNextLegacyId(realm)
        newTask = realm.create('AsyncTask', {
          _id: new Realm.BSON.ObjectId(),
          id: nextId,
          task_type: input.task_type,
          business_data: JSON.stringify(input.business_data),
          status: input.status || TaskStatus.PENDING,
          progress: 0,
          error_message: null,
          result_data: null,
          created_at: now,
          updated_at: now,
          started_at: null,
          completed_at: null
        }) as AsyncTaskModel
      })

      console.log(`✅ 异步任务创建成功: ${input.task_type}`)

      return {
        success: true,
        data: this.parseTaskModel(newTask!)
      }
    } catch (error) {
      console.error('❌ 创建异步任务失败:', error)
      return {
        success: false,
        error: `创建异步任务失败: ${error}`
      }
    }
  }

  /**
   * 更新异步任务
   * @param id 任务ID
   * @param input 更新数据
   * @returns 操作结果
   */
  async updateTask(
    id: string,
    input: Omit<UpdateAsyncTaskInput, 'id'>
  ): Promise<DatabaseResult<ParsedAsyncTask>> {
    try {
      const realm = getDatabase()
      const objectId = new Realm.BSON.ObjectId(id)
      const task = realm.objectForPrimaryKey(AsyncTaskModel, objectId) as AsyncTaskModel

      if (!task) {
        return {
          success: false,
          error: '任务不存在'
        }
      }

      realm.write(() => {
        if (input.status !== undefined) {
          task.status = input.status

          // 自动设置时间戳
          if (input.status === TaskStatus.IN_PROGRESS && !task.started_at) {
            task.started_at = new Date()
          }

          if (
            (input.status === TaskStatus.COMPLETED || input.status === TaskStatus.FAILED) &&
            !task.completed_at
          ) {
            task.completed_at = new Date()
          }
        }

        if (input.progress !== undefined) task.progress = input.progress
        if (input.error_message !== undefined) task.error_message = input.error_message
        if (input.result_data !== undefined) {
          task.result_data = input.result_data ? JSON.stringify(input.result_data) : null
        }
        if (input.business_data !== undefined) {
          task.business_data = JSON.stringify(input.business_data)
        }

        task.updated_at = new Date()
      })

      console.log(`✅ 异步任务更新成功: ID ${id}`)
      return {
        success: true,
        data: this.parseTaskModel(task)
      }
    } catch (error) {
      console.error('❌ 更新异步任务失败:', error)
      return {
        success: false,
        error: `更新异步任务失败: ${error}`
      }
    }
  }

  /**
   * 更新任务进度
   * @param id 任务ID
   * @param progress 进度百分比 (0-100)
   * @returns 操作结果
   */
  async updateProgress(id: string, progress: number): Promise<DatabaseResult<ParsedAsyncTask>> {
    return await this.updateTask(id, { progress })
  }

  /**
   * 标记任务为进行中
   * @param id 任务ID
   * @returns 操作结果
   */
  async markAsInProgress(id: string): Promise<DatabaseResult<ParsedAsyncTask>> {
    return await this.updateTask(id, { status: TaskStatus.IN_PROGRESS })
  }

  /**
   * 标记任务为已完成
   * @param id 任务ID
   * @param resultData 任务结果数据（可选）
   * @returns 操作结果
   */
  async markAsCompleted(
    id: string,
    resultData?: Record<string, any>
  ): Promise<DatabaseResult<ParsedAsyncTask>> {
    return await this.updateTask(id, {
      status: TaskStatus.COMPLETED,
      progress: 100,
      result_data: resultData
    })
  }

  /**
   * 标记任务为失败
   * @param id 任务ID
   * @param errorMessage 错误信息
   * @returns 操作结果
   */
  async markAsFailed(id: string, errorMessage: string): Promise<DatabaseResult<ParsedAsyncTask>> {
    return await this.updateTask(id, {
      status: TaskStatus.FAILED,
      error_message: errorMessage
    })
  }

  /**
   * 删除异步任务
   * @param id 任务ID
   * @returns 操作结果
   */
  async deleteTask(id: string): Promise<DatabaseResult<void>> {
    try {
      const realm = getDatabase()
      const objectId = new Realm.BSON.ObjectId(id)
      const task = realm.objectForPrimaryKey(AsyncTaskModel, objectId) as AsyncTaskModel

      if (!task) {
        return {
          success: false,
          error: '任务不存在'
        }
      }

      realm.write(() => {
        realm.delete(task)
      })

      console.log(`✅ 异步任务删除成功: ID ${id}`)
      return {
        success: true
      }
    } catch (error) {
      console.error('❌ 删除异步任务失败:', error)
      return {
        success: false,
        error: `删除异步任务失败: ${error}`
      }
    }
  }

  /**
   * 根据ID查找任务
   * @param id 任务ID
   * @returns 查找结果
   */
  async findById(id: string): Promise<DatabaseResult<ParsedAsyncTask | null>> {
    try {
      const realm = getDatabase()
      const objectId = new Realm.BSON.ObjectId(id)
      const task = realm.objectForPrimaryKey(AsyncTaskModel, objectId) as AsyncTaskModel | null

      return {
        success: true,
        data: task ? this.parseTaskModel(task) : null
      }
    } catch (error) {
      console.error('❌ 根据ID查找任务失败:', error)
      return {
        success: false,
        error: `根据ID查找任务失败: ${error}`
      }
    }
  }

  /**
   * 查询异步任务
   * @param params 查询参数
   * @returns 查询结果
   */
  async queryTasks(params: QueryAsyncTaskParams = {}): Promise<DatabaseResult<ParsedAsyncTask[]>> {
    try {
      const realm = getDatabase()
      let results = realm.objects('AsyncTask')

      // 构建查询条件
      const filters: string[] = []
      const filterArgs: any[] = []

      if (params.task_type) {
        filters.push('task_type == $' + filterArgs.length)
        filterArgs.push(params.task_type)
      }

      if (params.status) {
        if (Array.isArray(params.status)) {
          const statusFilters = params.status.map(
            (_, idx) => `status == $${filterArgs.length + idx}`
          )
          filters.push(`(${statusFilters.join(' OR ')})`)
          filterArgs.push(...params.status)
        } else {
          filters.push('status == $' + filterArgs.length)
          filterArgs.push(params.status)
        }
      }

      if (params.created_after) {
        filters.push('created_at >= $' + filterArgs.length)
        filterArgs.push(params.created_after)
      }

      if (params.created_before) {
        filters.push('created_at <= $' + filterArgs.length)
        filterArgs.push(params.created_before)
      }

      // 应用过滤器
      if (filters.length > 0) {
        const filterString = filters.join(' AND ')
        results = results.filtered(filterString, ...filterArgs)
      }

      // 排序
      const sortBy = params.sortBy || 'created_at'
      const sortOrder = params.sortOrder === 'asc'
      results = results.sorted(sortBy, sortOrder)

      // 分页
      const offset = params.offset || 0
      const limit = params.limit || 100
      const slicedResults = Array.from(
        results.slice(offset, offset + limit)
      ) as unknown as AsyncTaskModel[]

      const parsedResults = slicedResults.map(task => this.parseTaskModel(task))

      console.log(`✅ 查询异步任务成功，返回 ${parsedResults.length} 条记录`)

      return {
        success: true,
        data: parsedResults,
        count: results.length
      }
    } catch (error) {
      console.error('❌ 查询异步任务失败:', error)
      return {
        success: false,
        error: `查询异步任务失败: ${error}`,
        data: []
      }
    }
  }

  /**
   * 获取待处理的任务
   * @param limit 返回记录数量
   * @returns 查询结果
   */
  async getPendingTasks(limit = 50): Promise<DatabaseResult<ParsedAsyncTask[]>> {
    return await this.queryTasks({
      status: TaskStatus.PENDING,
      limit,
      sortBy: 'created_at',
      sortOrder: 'asc'
    })
  }

  /**
   * 获取进行中的任务
   * @param limit 返回记录数量
   * @returns 查询结果
   */
  async getInProgressTasks(limit = 50): Promise<DatabaseResult<ParsedAsyncTask[]>> {
    return await this.queryTasks({
      status: TaskStatus.IN_PROGRESS,
      limit,
      sortBy: 'started_at',
      sortOrder: 'desc'
    })
  }

  /**
   * 获取已完成的任务
   * @param limit 返回记录数量
   * @returns 查询结果
   */
  async getCompletedTasks(limit = 50): Promise<DatabaseResult<ParsedAsyncTask[]>> {
    return await this.queryTasks({
      status: TaskStatus.COMPLETED,
      limit,
      sortBy: 'completed_at',
      sortOrder: 'desc'
    })
  }

  /**
   * 获取失败的任务
   * @param limit 返回记录数量
   * @returns 查询结果
   */
  async getFailedTasks(limit = 50): Promise<DatabaseResult<ParsedAsyncTask[]>> {
    return await this.queryTasks({
      status: TaskStatus.FAILED,
      limit,
      sortBy: 'updated_at',
      sortOrder: 'desc'
    })
  }

  /**
   * 根据任务类型获取任务
   * @param taskType 任务类型
   * @param limit 返回记录数量
   * @returns 查询结果
   */
  async getTasksByType(taskType: string, limit = 50): Promise<DatabaseResult<ParsedAsyncTask[]>> {
    return await this.queryTasks({
      task_type: taskType,
      limit,
      sortBy: 'created_at',
      sortOrder: 'desc'
    })
  }

  /**
   * 获取任务总数
   * @returns 任务总数
   */
  async getTaskCount(): Promise<DatabaseResult<number>> {
    try {
      const realm = getDatabase()
      const count = realm.objects('AsyncTask').length

      return {
        success: true,
        data: count
      }
    } catch (error) {
      console.error('❌ 获取任务总数失败:', error)
      return {
        success: false,
        error: `获取任务总数失败: ${error}`,
        data: 0
      }
    }
  }

  /**
   * 批量删除任务
   * @param ids 要删除的任务ID数组
   * @returns 操作结果
   */
  async deleteTasks(ids: string[]): Promise<DatabaseResult<void>> {
    try {
      if (ids.length === 0) {
        return { success: true, count: 0 }
      }

      const realm = getDatabase()
      let deletedCount = 0

      realm.write(() => {
        for (const id of ids) {
          const objectId = new Realm.BSON.ObjectId(id)
          const task = realm.objectForPrimaryKey('AsyncTask', objectId)
          if (task) {
            realm.delete(task)
            deletedCount++
          }
        }
      })

      console.log(`✅ 批量删除异步任务成功，删除了 ${deletedCount} 条记录`)

      return {
        success: true,
        count: deletedCount
      }
    } catch (error) {
      console.error('❌ 批量删除异步任务失败:', error)
      return {
        success: false,
        error: `批量删除异步任务失败: ${error}`
      }
    }
  }

  /**
   * 清理已完成的任务
   * @param olderThanDays 清理多少天前的已完成任务（默认30天）
   * @returns 操作结果
   */
  async cleanupCompletedTasks(olderThanDays = 30): Promise<DatabaseResult<void>> {
    try {
      const realm = getDatabase()
      const cutoffDate = new Date()
      cutoffDate.setDate(cutoffDate.getDate() - olderThanDays)

      const tasksToDelete = realm
        .objects('AsyncTask')
        .filtered('status == $0 AND completed_at < $1', TaskStatus.COMPLETED, cutoffDate)

      const count = tasksToDelete.length

      realm.write(() => {
        realm.delete(tasksToDelete)
      })

      console.log(`✅ 清理已完成任务成功，删除了 ${count} 条记录`)

      return {
        success: true,
        count
      }
    } catch (error) {
      console.error('❌ 清理已完成任务失败:', error)
      return {
        success: false,
        error: `清理已完成任务失败: ${error}`
      }
    }
  }

  /**
   * 清理失败的任务
   * @param olderThanDays 清理多少天前的失败任务（默认7天）
   * @returns 操作结果
   */
  async cleanupFailedTasks(olderThanDays = 7): Promise<DatabaseResult<void>> {
    try {
      const realm = getDatabase()
      const cutoffDate = new Date()
      cutoffDate.setDate(cutoffDate.getDate() - olderThanDays)

      const tasksToDelete = realm
        .objects('AsyncTask')
        .filtered('status == $0 AND updated_at < $1', TaskStatus.FAILED, cutoffDate)

      const count = tasksToDelete.length

      realm.write(() => {
        realm.delete(tasksToDelete)
      })

      console.log(`✅ 清理失败任务成功，删除了 ${count} 条记录`)

      return {
        success: true,
        count
      }
    } catch (error) {
      console.error('❌ 清理失败任务失败:', error)
      return {
        success: false,
        error: `清理失败任务失败: ${error}`
      }
    }
  }

  /**
   * 清空所有任务
   * @returns 操作结果
   */
  async clearAllTasks(): Promise<DatabaseResult<void>> {
    try {
      const realm = getDatabase()
      const allTasks = realm.objects('AsyncTask')
      const count = allTasks.length

      realm.write(() => {
        realm.delete(allTasks)
      })

      console.log(`✅ 清空所有任务成功，删除了 ${count} 条记录`)

      return {
        success: true,
        count
      }
    } catch (error) {
      console.error('❌ 清空所有任务失败:', error)
      return {
        success: false,
        error: `清空所有任务失败: ${error}`
      }
    }
  }

  /**
   * 通过兼容数值ID查找任务
   */
  async findByLegacyId(id: number): Promise<DatabaseResult<ParsedAsyncTask | null>> {
    try {
      const realm = getDatabase()
      const task = realm.objects('AsyncTask').filtered('id == $0', id)[0] as unknown as
        | AsyncTaskModel
        | undefined
      return {
        success: true,
        data: task ? this.parseTaskModel(task) : null
      }
    } catch (error) {
      console.error('❌ 根据数值ID查找任务失败:', error)
      return {
        success: false,
        error: `根据数值ID查找任务失败: ${error}`
      }
    }
  }

  /**
   * 通过兼容数值ID更新任务
   */
  async updateTaskByLegacyId(
    id: number,
    input: Omit<UpdateAsyncTaskInput, 'id'>
  ): Promise<DatabaseResult<ParsedAsyncTask>> {
    try {
      const realm = getDatabase()
      const task = realm.objects('AsyncTask').filtered('id == $0', id)[0] as unknown as
        | AsyncTaskModel
        | undefined
      if (!task) return { success: false, error: '任务不存在' }

      const objectId = task._id.toHexString()
      return await this.updateTask(objectId, input)
    } catch (error) {
      console.error('❌ 通过数值ID更新任务失败:', error)
      return {
        success: false,
        error: `通过数值ID更新任务失败: ${error}`
      }
    }
  }

  /**
   * 通过兼容数值ID删除任务
   */
  async deleteTaskByLegacyId(id: number): Promise<DatabaseResult<void>> {
    try {
      const realm = getDatabase()
      const task = realm.objects('AsyncTask').filtered('id == $0', id)[0] as unknown as
        | AsyncTaskModel
        | undefined
      if (!task) return { success: false, error: '任务不存在' }
      realm.write(() => {
        realm.delete(task)
      })
      return { success: true }
    } catch (error) {
      console.error('❌ 通过数值ID删除任务失败:', error)
      return {
        success: false,
        error: `通过数值ID删除任务失败: ${error}`
      }
    }
  }

  /**
   * 通过兼容数值ID批量删除任务
   */
  async deleteTasksByLegacyIds(ids: number[]): Promise<DatabaseResult<void>> {
    try {
      if (ids.length === 0) {
        return { success: true, count: 0 }
      }

      const realm = getDatabase()
      let deletedCount = 0

      realm.write(() => {
        for (const id of ids) {
          const task = realm.objects('AsyncTask').filtered('id == $0', id)[0]
          if (task) {
            realm.delete(task)
            deletedCount++
          }
        }
      })

      console.log(`✅ 批量删除异步任务成功，删除了 ${deletedCount} 条记录`)

      return {
        success: true,
        count: deletedCount
      }
    } catch (error) {
      console.error('❌ 批量删除异步任务失败:', error)
      return {
        success: false,
        error: `批量删除异步任务失败: ${error}`
      }
    }
  }

  /**
   * 通过兼容数值ID更新进度
   */
  async updateProgressByLegacyId(
    id: number,
    progress: number
  ): Promise<DatabaseResult<ParsedAsyncTask>> {
    return await this.updateTaskByLegacyId(id, { progress })
  }

  /**
   * 通过兼容数值ID标记任务为进行中
   */
  async markAsInProgressByLegacyId(id: number): Promise<DatabaseResult<ParsedAsyncTask>> {
    return await this.updateTaskByLegacyId(id, { status: TaskStatus.IN_PROGRESS })
  }

  /**
   * 通过兼容数值ID标记任务为已完成
   */
  async markAsCompletedByLegacyId(
    id: number,
    resultData?: Record<string, any>
  ): Promise<DatabaseResult<ParsedAsyncTask>> {
    return await this.updateTaskByLegacyId(id, {
      status: TaskStatus.COMPLETED,
      progress: 100,
      result_data: resultData
    })
  }

  /**
   * 通过兼容数值ID标记任务为失败
   */
  async markAsFailedByLegacyId(
    id: number,
    errorMessage: string
  ): Promise<DatabaseResult<ParsedAsyncTask>> {
    return await this.updateTaskByLegacyId(id, {
      status: TaskStatus.FAILED,
      error_message: errorMessage
    })
  }
}
